package org.tgcloud.group.service.manager;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.tgcloud.group.core.APPResultMessage;
import org.tgcloud.group.core.DateUtil;
import org.tgcloud.group.core.ResultMessage;
import org.tgcloud.group.core.StringUtil;
import org.tgcloud.group.entity.MjMediumOffline;
import org.tgcloud.group.repository.MjMediumOfflineMapper;
import org.tgcloud.group.repository.MjProjectMapper;
import org.tgcloud.group.repository.MjProjectMediumMapper;
import org.tgcloud.group.web.controller.dto.medium.MediumCountProjectDTO;
import org.tgcloud.group.web.controller.dto.medium.MediumOfflineCountDTO;
import org.tgcloud.group.web.controller.dto.medium.MediumOnlineDTO;
import org.tgcloud.group.web.controller.dto.medium.ProjectMediumCountDTO;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author: zhy
 * @create: 2023-12-18 09:35
 * @description:
 */
@Service
public class MediumCountManagerService {

    @Autowired
    private MjMediumOfflineMapper mediumOfflineMapper;

    @Autowired
    private MjProjectMediumMapper projectMediumMapper;

    @Autowired
    private MjProjectMapper projectMapper;

    public APPResultMessage<Object, MediumOfflineCountDTO> getMediumCountList(Integer pageNum, Integer pageSize, String projectIds, Date startTime, Date endTime) {
        String[] projectIdList = null;
        if (StringUtil.isNotBlank(projectIds)){
            projectIdList = projectIds.split(",");
        }
        if (pageNum != null && pageSize != null){
            PageHelper.startPage(pageNum, pageSize);
            List<MediumOfflineCountDTO> dtos = mediumOfflineMapper.selectCountList();
            PageInfo<MediumOfflineCountDTO> tables = new PageInfo<>(dtos);
            for (MediumOfflineCountDTO dto : tables.getList()){
                doSetOfflineCount(dto, projectIdList, startTime, endTime);
            }
            ResultMessage result = ResultMessage.builder().setList(tables.getList()).setAllPageNumber(tables.getPages()).setCount(tables.getTotal());
            APPResultMessage<Object, MediumOfflineCountDTO> message = APPResultMessage.getSuccessMessage();
            message.setResult(result);
            return message;
        }else {
            List<MediumOfflineCountDTO> dtos = mediumOfflineMapper.selectCountList();
            for (MediumOfflineCountDTO dto : dtos){
                doSetOfflineCount(dto, projectIdList, startTime, endTime);
            }
            ResultMessage resultMessage = ResultMessage.builder().setList(dtos);
            APPResultMessage<Object, MediumOfflineCountDTO> successMessage = APPResultMessage.getSuccessMessage();
            successMessage.setResult(resultMessage);
            return successMessage;
        }
    }

    // 计算统计数据
    public MediumOfflineCountDTO doSetOfflineCount(MediumOfflineCountDTO dto, String[] projectIdList, Date startTime, Date endTime){
//        1、媒体的项目占比p=该媒体的匹配货值/该项目所有媒体的匹配货值之和
//        2、项目客户货值 s
//        3、项目收入 t
//        4、该媒体单次成本 a
//        5、某项目中该媒体数量 b
//        6、该媒体在某项目中 在某时间段内上刊的天数Cn
//        7、该媒体在项目中的总天数 C
//        8、上刊率：一段时间内，该媒体被占用的天数/媒体总天数   d
//        eg:月30天，媒体上刊数4，媒体总天数为120，若被占用30天，则d=30/120
        BigDecimal p = BigDecimal.ZERO;
        BigDecimal s = BigDecimal.ZERO;
        BigDecimal t = BigDecimal.ZERO;
        BigDecimal a = dto.getCost();
        BigDecimal b = BigDecimal.ZERO;
        BigDecimal Cn = BigDecimal.ZERO;
        BigDecimal c = BigDecimal.ZERO;
        List<ProjectMediumCountDTO> countDTOS = projectMediumMapper.selectProjectListByMediumId(dto.getId(), projectIdList, startTime, endTime);
        for (ProjectMediumCountDTO countDTO : countDTOS){
            b = new BigDecimal(countDTO.getNum());
            s = countDTO.getTotalPrice() != null ? countDTO.getTotalPrice() : BigDecimal.ZERO;
            t = (countDTO.getBlindRealPrice() != null && countDTO.getBlindRealPrice().compareTo(BigDecimal.ZERO) > 0)
                    || (countDTO.getSaleRealPrice() != null && countDTO.getSaleRealPrice().compareTo(BigDecimal.ZERO) > 0) ?
                    ((countDTO.getBlindRealPrice() != null ? countDTO.getBlindRealPrice() : BigDecimal.ZERO).add(countDTO.getSaleRealPrice() != null ? countDTO.getSaleRealPrice() : BigDecimal.ZERO))
                    : ((countDTO.getBlindBoxPrice() != null ? countDTO.getBlindBoxPrice() : BigDecimal.ZERO).add(countDTO.getCheckCostPrice() != null ? countDTO.getCheckCostPrice() : BigDecimal.ZERO));

            BigDecimal oneProjectTotalGoodPrice = projectMediumMapper.selectTotalGoodPriceByProjectId(countDTO.getProjectId());
            if (oneProjectTotalGoodPrice.compareTo(BigDecimal.ZERO) > 0){
                p = countDTO.getGoodPrice().divide(oneProjectTotalGoodPrice, 4, BigDecimal.ROUND_HALF_UP);


                // 存在时间段的处理
                if (startTime != null && endTime!= null) {
                    // 计算两段时间，如果选择的时间超过了筛选的时间，那么使用筛选的时间作为开始时间，结束时间也是如此
                    Date time1 = countDTO.getChooseTime();
                    Date time2 = countDTO.getChooseEndTime();
                    if (time1.getTime() < startTime.getTime()) {
                        time1 = startTime;
                    }
                    if (time2.getTime() > endTime.getTime()) {
                        time2 = endTime;
                    }
                    List<Date> dateList = DateUtil.getDateListByStartTimeAndEndTime(time1, time2);
                    // 媒体在某项目中 在某时间段内上刊的天数Cn
                    Cn = new BigDecimal(dateList.size());
                    // 媒体在项目中的总天数 c
                    Integer day = DateUtil.getDateListByStartTimeAndEndTime(countDTO.getChooseTime(), countDTO.getChooseEndTime()).size();
                    c = new BigDecimal(day);
                    // 该媒体所占项目份额 h = p * Cn/C
                    if (c != null && c.compareTo(BigDecimal.ZERO) > 0){
                        BigDecimal h = p.multiply(Cn).divide(c, 4, BigDecimal.ROUND_HALF_UP);
                        dto.setMediumRateProject(dto.getMediumRateProject().add(h));
                        // 成本：a/天数*时间段
                        BigDecimal cost = a.divide(c, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(countDTO.getNum()));
                        dto.setMediumCost(dto.getMediumCost().add(cost));
                        // 媒体收入：t*h
                        dto.setMediumIncome(dto.getMediumIncome().add(t.multiply(h)));
                        // 媒体毛利：t*h - 成本
                        dto.setMediumGrossProfit(dto.getMediumGrossProfit().add(t.multiply(h).subtract(cost)));
                        // 媒体货值：s*h
                        dto.setMediumValue(dto.getMediumValue().add(s.multiply(h)));
                        // 上刊率：一段时间内，该媒体被占用的天数/媒体总天数   d
                        List<Date> dateAllList = DateUtil.getDateListByStartTimeAndEndTime(startTime, endTime);
                        BigDecimal allDayNum = new BigDecimal(dto.getNum()).multiply(new BigDecimal(dateAllList.size()));
                        BigDecimal d = Cn.divide(allDayNum, 4, BigDecimal.ROUND_HALF_UP);
                        dto.setMediumRateNum(dto.getMediumRateNum().add(d));
                    }
                }else {
                    // 没有选择时间的情况
                    // 媒体收入 t*p
                    BigDecimal p1 = t.multiply(p);
                    dto.setMediumIncome(dto.getMediumIncome().add(p1));
                    // 媒体毛利：t*p - a*b
                    dto.setMediumGrossProfit(dto.getMediumGrossProfit().add(p1.subtract(a.multiply(b))));
                    // 媒体货值：s*p
                    dto.setMediumValue(dto.getMediumValue().add(s.multiply(p)));
                    // 媒体成本：a*b
                    dto.setMediumCost(dto.getMediumCost().add(a.multiply(b)));
                }
            }

        }


        // 倍差：媒体收入/媒体成本
        if (dto.getMediumCost() != null && dto.getMediumCost().compareTo(BigDecimal.ZERO) > 0){
            dto.setMediumRate(dto.getMediumIncome().divide(dto.getMediumCost(), 4, BigDecimal.ROUND_HALF_UP));
        }
        return dto;
    }

    public APPResultMessage getProjectListFromMediumCount() {
        List<MediumCountProjectDTO> list = projectMapper.selectProjectListFromMediumCount();
        APPResultMessage successMessage = APPResultMessage.getSuccessMessage();
        ResultMessage resultMessage = ResultMessage.builder().setList(list);
        successMessage.setResult(resultMessage);
        return successMessage;
    }
}
